package com.dmz.czykt.run;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.dmz.czykt.config.Constants;
import com.dmz.czykt.util.CzyktSftpFileUtil;
import com.dmz.czykt.util.EncryptUtil;
import com.dmz.czykt.util.HttpClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

/**
 * @author lee
 */
@Slf4j
@Component
public class CzyktServer {


    @Value("${listenPort}")
    private int listenPort;

    @Value("${cspIps}")
    private String cspIps;

    @Value("${bpsIp}")
    private String bpsIp;
    //	@Value("${localPath}")
//	private String localPath;
    @Value("${key}")
    private String key;
    @Value("${sftpUserName}")
    private String sftpUserName;
    @Value("${sftpPasswd}")
    private String sftpPasswd;
    @Value("${sftpIP}")
    private String sftpIP;
    @Value("${sftpPort}")
    private int sftpPort;
    //	@Value("${sftpDir}")
//	private String sftpDir;
    @Value("${url2}")
    private String url2;

    @Value("${bpsftpUserName}")
    private String bpsftpUserName1;
    @Value("${bpsftpPasswd}")
    private String bpsftpPasswd1;
    @Value("${bpsftpIP}")
    private String bpsftpIP;
    @Value("${bpsftpPort}")
    private int bpsftpPort;
//	@Value("${bpsftpDown}")
//	private String bpsftpDown;

    @Value("${sm4.key}")
    private String sm4key;

    @Value("${sm4.iv}")
    private String iv;

    // 监听端口，默认7111

    private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    /**
     * 启动监听Csp ServerSocket
     */
    public void startServer() {
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(listenPort);
            System.out
                    .println(Charset.defaultCharset().displayName() + "TCP Server[" + listenPort + "]已经启动，开始监听......");
            log.info("TCP Server[{}]已经启动，开始监听......", listenPort);
            while (true) {
                Socket listenSocket = serverSocket.accept();
                String ip = listenSocket.getInetAddress().toString();

                String[] ips = cspIps.split(",");
                if (Arrays.asList(ips).contains(ip)) {
                    System.out.println("server 接受到 【csp】 请求的时间：" + sdf2.format(new Date()));
                    System.out.println("接收到请求...");
                    log.info("server 接受到 【csp】 请求：");
                    // 这个函数中的代码出现异常不能影响socket服务器的继续运行
                    try {
                        processCspRequest(listenSocket);
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                } else if (ip.contains(bpsIp)) {
                    try {
                        processBpsRequest(listenSocket);
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }
                System.out.println("TCP server 结束处理：" + sdf2.format(new Date()));
                log.info("TCP server 结束处理");
                log.info("");
            }
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
    }

    private void processBpsRequest(Socket bpsSocket) throws Exception {
        InputStream inp = null;
        InputStreamReader isr = null;
        BufferedReader bfr = null;
        OutputStream ots = null;
        String info = "";
        String Message = "";
        String localPath = Constants.localPath;
        String sftpDir = Constants.sftpDir;
        String bpsftpDown = Constants.bpsftpDown;

        try {
            inp = bpsSocket.getInputStream();
            isr = new InputStreamReader(inp, StandardCharsets.UTF_8);
            bfr = new BufferedReader(isr);
            info = bfr.readLine();
            String in = info;
            System.out.println("接收bps报文：" + in);
            String bpsMessage = in;
            log.info("接收bps报文：{}", bpsMessage);
            String sftpuser = sftpUserName;
            String sftpPassword = sftpPasswd;

            String id = bpsMessage.split("\\|", -1)[0].trim();
            String uuid = bpsMessage.split("\\|", -1)[1].trim();
            String callDate = bpsMessage.split("\\|", -1)[2].trim();
            String callTime = bpsMessage.split("\\|", -1)[3].trim();
            String callUser = bpsMessage.split("\\|", -1)[4].trim();
            String areaCode = bpsMessage.split("\\|", -1)[5].trim();
            String bankNo = bpsMessage.split("\\|", -1)[6].trim();
            String fileName = bpsMessage.split("\\|", -1)[7].trim();
            String result = bpsMessage.split("\\|", -1)[8].trim();
            String resultReason = bpsMessage.split("\\|", -1)[9].trim();
            int amtSum = Integer.parseInt(bpsMessage.split("\\|", -1)[10].trim());
            int rowCnt = Integer.parseInt(bpsMessage.split("\\|", -1)[11].trim());
            int sucAmt = Integer.parseInt(bpsMessage.split("\\|", -1)[12].trim());
            int sucRowCnt = Integer.parseInt(bpsMessage.split("\\|", -1)[13].trim());
            String extend1 = bpsMessage.split("\\|", -1)[14].trim();
            String extend2 = bpsMessage.split("\\|", -1)[15].trim();

            //bps下载文件
            String bpsftpUserName = bpsftpUserName1;
            String bpsftpPasswd = bpsftpPasswd1;


            // 使用安全文件名进行后续操作
            boolean bpsFlag = CzyktSftpFileUtil.DownFile(fileName, bpsftpUserName, bpsftpPasswd,
                    bpsftpIP, bpsftpPort, localPath, bpsftpDown);
            if (bpsFlag) {
                CzyktSftpFileUtil sftp = new CzyktSftpFileUtil();

                // 使用安全文件名构建完整路径
                String safeFilePath = localPath + fileName;


                EncryptUtil.readTxtGB218030(safeFilePath); // 文件转码GB18030
                EncryptUtil.encryptEcbTxt(safeFilePath, key); // 文件GB18030 加密

                sftp.ConnectUpload(sftpuser, sftpPassword, sftpIP, sftpPort, sftpDir, safeFilePath);

                // 通知第三方 - 使用安全文件名
                String json = "{\"head\":{\"id\":\"" + id + "\",\"uuid\":\"" + uuid + "\",\"callDate\":\"" + callDate + "\",\"callTime\":\"" + callTime + "\",\"callUser\":\"" + callUser + "\",\"areaCode\":\"" + areaCode + "\",\"bankNo\":\"" + bankNo + "\"},\"data\":{\"fileName\":\"" + fileName + "\",\"result\":\"" + result + "\",\"resultReason\":\"" + resultReason + "\",\"amtSum\":" + amtSum + ",\"rowCnt\":" + rowCnt + ",\"sucAmt\":" + sucAmt + ",\"sucRowCnt\":" + sucRowCnt + ",\"extend1\":\"" + extend1 + "\",\"extend2\":\"" + extend2 + "\"}}";

                try {
                    log.info("上传sftp文件成功：{}", fileName);
                    System.out.println(json);
                    JSONObject resjson = HttpClient.doPost2(url2, json);
                    log.info("财政返回返回报文为：\n{}", Objects.requireNonNull(resjson));
                    String rescode = resjson.getStr("code");
                    String resMessage = "0000";
                    if (!"200".equals(rescode)) {
                        resMessage = "9999" + resjson.getStr("error");
                    }
                    ots = bpsSocket.getOutputStream();
                    byte[] data = resMessage.getBytes("GBK");
                    if (data != null) {
                        String output = new String(data, "GBK");
                        System.out.println("=============" + output.length());
                        log.info("返回报文为：\n {}", output);
                        ots.write(data);
                    }

                } catch (Exception e) {
                    log.error("上传sftp文件失败：{}", fileName, e);
                }
            }

        } catch (Exception e) {
            log.error("程序异常错误：", e);
        } finally {
            // 原有finally代码保持不变
            try {
                if (ots != null) {
                    ots.close();
                }
                if (bfr != null) {
                    bfr.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (inp != null) {
                    inp.close();
                }
            } catch (IOException e) {
                log.error("程序异常错误：", e);
            }
        }
    }

    // 处理csp请求
    private String processCspRequest(Socket cspSocket) {
        InputStream inp = null;
        InputStreamReader isr = null;
        BufferedReader bfr = null;
        OutputStream ots = null;
        String info = "";
        String Message = "";
        try {
            inp = cspSocket.getInputStream();
            isr = new InputStreamReader(inp, StandardCharsets.UTF_8);
            bfr = new BufferedReader(isr);
            info = bfr.readLine();
            String in = info;
            String sbMessage = in;// new String(recBuffer,AppValues.csn_U8);
            log.info("报文数据{}", sbMessage);
            Object[] objects = null;
            if (sbMessage.length() > 4) {// 长度判断
                String str = sbMessage;// "{\"functionName\":[\"123\",\"456\",\"4526\"]}";
                JSONObject json = JSONUtil.parseObj(str);
                json.remove("functionName");
            }
            String result = "";
            ots = cspSocket.getOutputStream();
            byte[] data = result.getBytes(StandardCharsets.UTF_8);
            if (data != null) {
                String output = new String(data, StandardCharsets.UTF_8);
                log.info("返回报文为：\n{}", output);
                ots.write(data);
            }
            ots.close();
            cspSocket.close();
        } catch (Exception e) {
            log.error("程序异常错误：", e);
        } finally {
            try {
                if (ots != null) {
                    ots.close();
                }
                if (bfr != null) {
                    bfr.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (inp != null) {
                    inp.close();
                }
            } catch (IOException e) {
                log.error("程序异常错误：", e);
            }

        }
        return "";
    }

}
